/*
 * spi_module.c
 *
 *  Created on: 2021年10月24日
 *      Author: zwr
 */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "LPC8xx.h"
#include "spi.h"
#include "syscon.h"
#include "swm.h"
#include "utilities.h"
#include "gpio.h"
#include "uart.h"
#include "chip_setup.h"
#include "serial_unit.h"

 void dac1220_init(void);
 void zwr_dac1220_init(void);

 void WriteOneByte(unsigned char command);
 void dac1220_set(unsigned char data1,unsigned char data2,unsigned char data3);
 void DAC1220_writeCode(uint32_t code);
 void DAC1220_writeV(double v);
 void delay1ms(void);         // delay 86*13*12/30 = 0.472ms
 void delay(int xx); 		  //50 * xx * 12 * 1 /30 us = 20 * xx us
 void delay_us(int time_us ); // time_us * 4 us
 void delay_ms(int time_ms);  // zwr 44-48ms * time_ms ?
 int sign(double x);
 double round(double r);
 void delay1ms(void);  // delay 86*13*12/30 = 0.472ms



extern unsigned char MySPIByte(unsigned char sdat,unsigned char cs,unsigned char rxignore);
extern int irq_flag;
extern  int Vcc;



void dac1220_set(unsigned char data1,unsigned char data2,unsigned char data3)
{
	CS_L;
	WriteOneByte(0x40);
	WriteOneByte(data1);
	WriteOneByte(data2);
	WriteOneByte(data3);
	//delay1ms;//no must
	CS_H;
}


void zwr_dac1220_init(void)
{
	//SCLK reset pattern
	CS_L; //RST = 0
	//delay_ms(30);

	CLK_L;  //SCLK = 0
	delay(500); // 10 000 us

	CLK_H;  //SCLK = 1
	delay(12);  //  204us < t1 《  320us

	CLK_L;  //SCLK = 0
	delay(10);  // t2 > 4us

	CLK_H;  //SCLK = 1
	delay(25);   //   409.6us <t3 < 720us

	CLK_L;  //SCLK = 0
	delay(20);  // t2 > 4us

	CLK_H;
	delay(43);  //   819us < t4 < 960us
	CLK_L;  //SCLK = 0


	delay_ms(5);//等待重启


	WriteOneByte(0x05);
	WriteOneByte(0xA1);
	CS_H;

	 //Wait 500ms for Self-Calibration to complete
	delay_ms(15);
}


void dac1220_init(void)
{
	//SCLK reset pattern
	CS_L; //RST = 0
	//delay_ms(30);

	CLK_L;  //SCLK = 0
	delay(500);
	CLK_H;  //SCLK = 1
	delay(500);
	CLK_L;  //SCLK = 0
	delay(10);
	CLK_H;  //SCLK = 1
	delay(1200);
	CLK_L;  //SCLK = 0
	delay(20);
	delay(2000);
	CLK_L;  //SCLK = 0
	CS_H;
	delay_ms(5);//等待重启


	CS_L;
	WriteOneByte(0x04);
	WriteOneByte(0x22);
	CS_H;
	//delay1ms;
	CS_L;
	WriteOneByte(0x05);
	WriteOneByte(0xe1);
	CS_H;
	//delay1ms;
}



void WriteOneByte(unsigned char command)
{
	unsigned char i;
	CLK_L;
	delay(5);
	for(i = 0; i < 8;i++)
	{
		CLK_H;
		delay(5); //500us  t3_min = 5 * 1/2.5=2us
		if(command&0x80)
			SDA_H;
		else
			SDA_L;
		command <<= 1;
		CLK_L;
		delay(5);
	}
}


void DAC1220_writeCode(uint32_t code) {

    dac1220_set((code&0x00FF0000)>>16,(code&0x0000FF00)>>8,(code&0x000000FF));
}

void DAC1220_writeV(double v) {
    uint32_t code;

    if (v < 0) {
        v = 0;
    } else if (v > 5) {
        v = 5;
    }

    code = (uint32_t)(v/5 * 0xFFFFF + 0.5);
    if (code > 0xFFFFF) {
        code = 0xFFFFF;
    }
    printf("Current Vcc : %lf\r\n",v);
    DAC1220_writeCode(code << 4);

}


int sign(double x)
{
	if(x>0)
     return 1;
    else if(x==0)
     return 0;
    else
     return -1;
}

double round(double r)
{
	return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
}


void delay1ms(void)  // delay 86*13*12/30 = 0.472ms
{
    unsigned char a,b;
        for(b=86;b>0;b--)
            for(a=13;a>0;a--);
}
void delay(int xx) //50 * xx * 12 * 1 /30 us = 20 * xx us
{
  int a,b;
 for(a=0;a<50;a++)
 for(b=xx;b>0;b--);
}


void delay_us(int time_us ) // time_us * 4 us
{
	int i,j;
	for( i=0;i<time_us;i++ )
	{
		for( j=0;j<11;j++ );//1us,  zwr4us?
	}
}

void delay_ms(int time_ms)  // zwr 44-48ms * time_ms ?
{
	int i;
	for( i=0;i<time_ms;i++ )
	{
		delay_us(11000);   //44-48ms
	}

}
/********************************       GP22_module        *******************************************/

float gp22_read_n_bytes(uint8_t n_bytes, uint8_t read_opcode, uint8_t read_addr, uint8_t fractional_bits)
{
	uint32_t    Result_read = 0,dat;
	float       Result = 0;
	uint8_t     read_opcode_addr = read_opcode | read_addr;
  //.............. Result = n Byte = n x 8 bits......................
	MySPIByte(read_opcode_addr,0,1); // READ OPCODE + Address
	for (int n = 0; n < n_bytes-1; n++)
    {
		dat=MySPIByte(0x00,0,0);
		Result_read=Result_read | (dat & 0xFF);
		Result_read<<=8;
    }
	dat=MySPIByte(0x00,1,0);
   	Result_read=Result_read | (dat & 0xFF);

   	Result = Result_read / pow(2, fractional_bits);
	return Result;
}
void gp22_wr_config_reg ( uint8_t opcode_address,  uint32_t config_reg_data)
{
	uint8_t Data_Byte_Lo    = config_reg_data;
	uint8_t Data_Byte_Mid1  = config_reg_data>>8;
	uint8_t Data_Byte_Mid2  = config_reg_data>>16;
	uint8_t Data_Byte_Hi    = config_reg_data>>24;

	MySPIByte(opcode_address,0,1);
	MySPIByte(Data_Byte_Hi,0,1);
	MySPIByte(Data_Byte_Mid2,0,1);
	MySPIByte(Data_Byte_Mid1,0,1);
	MySPIByte(Data_Byte_Lo,1,1);

}
